import { _decorator, Component, instantiate, Layout, Node } from 'cc';
import { AssetList, Direction, Global } from '../Global';
import { ResMgr } from '../Mgr/ResMgr';
import { GameSingleSprite, SpriteInfo } from './GameSingleSprite';
import { UIMgr } from '../Mgr/UIMgr';
import { TopPrompt } from '../Top/TopPrompt';
import { EleScoreLoad } from './EleScoreLoad';
import { GameScene } from './GameScene';
import { GAMEDATA } from './GAMEDATA';
import { AudioMgr, SoundName } from '../Mgr/AudioMgr';
const { ccclass, property } = _decorator;

@ccclass('EleLoad')
export class EleLoad extends Component {

    //背景层
    @property(Node)
    private BgLoad: Node = null;

    //精灵层
    @property(Node)
    private SpriteLoad: Node = null;

    //分数层
    @property(Node)
    private ScreoLoad: Node = null;

    //提示层
    @property(Node)
    private UpLoad: Node = null;
    @property(Node)
    private DownLoad: Node = null;
    @property(Node)
    private LeftLoad: Node = null;
    @property(Node)
    private RightLoad: Node = null;

    //精灵数组
    private SpriteArr: Node[][] = [];

    //移动方向
    private CurDirection: string = "";

    //相邻得数组
    private NeightSameSprites: Node[] = [];

    ///整体相同得精灵
    private AllAddScoreSprites: Node[] = [];

    //横向是否可以移动
    public HorCanMove: boolean = true;
    public VerCanMove: boolean = true;

    protected start(): void {
        this.Init();
    }

    /**
     *  初始化
     */
    public Init() {
        UIMgr.Instance.ShowTop(AssetList.Top.NoTouch);
        //整体区域宽度
        let all_width: number = Global.HorNum * Global.BrickDis;
        let all_height: number = Global.VerNum * Global.BrickDis;

        //精灵索引
        let sprite_index: number = 0;

        for (let i = 0; i < Global.HorNum; i++) {
            let hor_sprites: Node[] = [];
            for (let j = 0; j < Global.VerNum; j++) {
                // let sprite_bg: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameEleBg]);
                // this.BgLoad.addChild(sprite_bg);
                // sprite_bg.setPosition(
                //     -all_width / 2 + (i + 0.5) * Global.BrickDis,
                //     -all_height / 2 + (j + 0.5) * Global.BrickDis,
                // )

                let single_sprite: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameSingleSprite]);
                this.SpriteLoad.addChild(single_sprite);
                single_sprite.getComponent(GameSingleSprite).Init();
                single_sprite.setPosition(
                    -all_width / 2 + (i + 0.5) * Global.BrickDis,
                    -all_height / 2 + (j + 0.5) * Global.BrickDis,
                )
                single_sprite.getComponent(GameSingleSprite).SpriteIndex = sprite_index;
                sprite_index++;
                hor_sprites.push(single_sprite);
            }
            this.SpriteArr.push(hor_sprites);
        }

        this.InitRoundSprite();

        //四周出现精灵
        // this.scheduleOnce(() => {
        this.UpdateAll();
        UIMgr.Instance.HideTop(AssetList.Top.NoTouch);
        // }, 1)
    }

    /**
     * 更新所有
     */
    public UpdateAll() {
        this.UpdateRoundSprite(this.UpLoad);
        this.UpdateRoundSprite(this.DownLoad);
        this.UpdateRoundSprite(this.LeftLoad);
        this.UpdateRoundSprite(this.RightLoad);
    }

    public ClearAll() {
        for (let i = 0; i < Global.HorNum; i++) {
            for (let j = 0; j < Global.VerNum; j++) {
                this.SpriteArr[i][j].getComponent(GameSingleSprite).Init();
            }
        }
    }

    /**
     * 初始化周围方向得方块
     */
    public InitRoundSprite() {
        //上下
        for (let i = 0; i < Global.HorNum; i++) {
            let upbrick: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameSingleSprite]);
            this.UpLoad.addChild(upbrick);
            upbrick.getComponent(GameSingleSprite).Init();

            let downbrick: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameSingleSprite]);
            this.DownLoad.addChild(downbrick);
            downbrick.getComponent(GameSingleSprite).Init();

            this.UpLoad.getComponent(Layout).spacingX = Global.BrickDis - Global.BrickWidth;
            this.DownLoad.getComponent(Layout).spacingX = Global.BrickDis - Global.BrickWidth;
        }

        //左右
        for (let i = 0; i < Global.VerNum; i++) {
            let leftbrick: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameSingleSprite]);
            this.LeftLoad.addChild(leftbrick);
            leftbrick.getComponent(GameSingleSprite).Init();

            let rightbrick: Node = instantiate(ResMgr.Instance.Prefabs[AssetList.Prefabs.GameSingleSprite]);
            this.RightLoad.addChild(rightbrick);
            rightbrick.getComponent(GameSingleSprite).Init();

            this.LeftLoad.getComponent(Layout).spacingY = Global.BrickDis - Global.BrickWidth;
            this.RightLoad.getComponent(Layout).spacingY = Global.BrickDis - Global.BrickWidth;
        }
    }

    /**
     * 更新周围得精灵
     */
    public UpdateRoundSprite(_node: Node) {
        _node.active = true;
        for (let sprite of _node.children) {
            let type_num: number = Math.floor(Math.random() * Global.SpriteType);
            sprite.getComponent(GameSingleSprite).UpdateSpriteStyle({ type: type_num });
            sprite.getComponent(GameSingleSprite).PlayAppearAni();
        }
    }
    /**
     * 滑动操作
     * @param 滑动方向
     */
    public SlideControl(_direction: string) {

        // //横向是否能操作
        // if ((_direction == Direction.LEFT || _direction == Direction.RIGHT) && !this.HorCanMove) {
        //     let top_prompt: Node = UIMgr.Instance.ShowTop(AssetList.Top.Prompt);
        //     top_prompt.getComponent(TopPrompt).UpdateContent("横向不能操作");
        //     return;
        // }
        // //纵向是否能操作
        // if ((_direction == Direction.UP || _direction == Direction.DOWN) && !this.VerCanMove) {
        //     let top_prompt: Node = UIMgr.Instance.ShowTop(AssetList.Top.Prompt);
        //     top_prompt.getComponent(TopPrompt).UpdateContent("纵向不能操作");
        //     return;
        // }

        //不能操作了
        UIMgr.Instance.ShowTop(AssetList.Top.NoTouch)

        this.CurDirection = _direction;
        //更新层级
        let update_load: Node = this.UpLoad;
        this.AllMove();//整体移动
        switch (_direction) {
            case Direction.UP:
                update_load = this.DownLoad;
                // this.DownLoad.active = false;
                for (let i = 0; i < this.SpriteArr.length; i++) {
                    if (this.SpriteArr[i][0].getComponent(GameSingleSprite).SpriteInfo.type == -1) {
                        this.SpriteArr[i][0].getComponent(GameSingleSprite).UpdateSpriteStyle(this.DownLoad.children[i].getComponent(GameSingleSprite).SpriteInfo)

                        let type_num: number = Math.floor(Math.random() * Global.SpriteType);
                        this.DownLoad.children[i].getComponent(GameSingleSprite).UpdateSpriteStyle({ type: type_num });
                        this.DownLoad.children[i].getComponent(GameSingleSprite).PlayAppearAni();
                    }
                }
                break;
            case Direction.DOWN:
                update_load = this.UpLoad;
                // this.UpLoad.active = false;
                for (let i = 0; i < this.SpriteArr.length; i++) {
                    if (this.SpriteArr[i][this.SpriteArr.length - 1].getComponent(GameSingleSprite).SpriteInfo.type == -1) {
                        this.SpriteArr[i][this.SpriteArr.length - 1].getComponent(GameSingleSprite).UpdateSpriteStyle(this.UpLoad.children[i].getComponent(GameSingleSprite).SpriteInfo)

                        let type_num: number = Math.floor(Math.random() * Global.SpriteType);
                        this.UpLoad.children[i].getComponent(GameSingleSprite).UpdateSpriteStyle({ type: type_num });
                        this.UpLoad.children[i].getComponent(GameSingleSprite).PlayAppearAni();
                    }
                }
                break;
            case Direction.LEFT:
                update_load = this.RightLoad;
                // this.RightLoad.active = false;
                for (let i = 0; i < this.SpriteArr.length; i++) {
                    if (this.SpriteArr[this.SpriteArr.length - 1][i].getComponent(GameSingleSprite).SpriteInfo.type == -1) {
                        this.SpriteArr[this.SpriteArr.length - 1][i].getComponent(GameSingleSprite).UpdateSpriteStyle(this.RightLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).SpriteInfo)

                        let type_num: number = Math.floor(Math.random() * Global.SpriteType);
                        this.RightLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).UpdateSpriteStyle({ type: type_num });
                        this.RightLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).PlayAppearAni();
                    }
                }
                break;
            case Direction.RIGHT:
                update_load = this.LeftLoad;
                // this.LeftLoad.active = false;
                for (let i = 0; i < Global.VerNum; i++) {
                    if (this.SpriteArr[0][i].getComponent(GameSingleSprite).SpriteInfo.type == -1) {
                        this.SpriteArr[0][i].getComponent(GameSingleSprite).UpdateSpriteStyle(this.LeftLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).SpriteInfo);

                        let type_num: number = Math.floor(Math.random() * Global.SpriteType);
                        this.LeftLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).UpdateSpriteStyle({ type: type_num });
                        this.LeftLoad.children[Global.HorNum - i - 1].getComponent(GameSingleSprite).PlayAppearAni();
                    }
                };
                break;
        }
        this.AllMove();
        this.scheduleOnce(() => {
            // this.UpdateRoundSprite(update_load);
            this.CheckDisappear();
        }, Global.SlideTime)
    }

    /**
     * 整体移动
     * @param 移动方向
     */
    private AllMove() {
        let is_play: boolean = false;
        switch (this.CurDirection) {
            case Direction.UP://整体向上移动
                for (let i = 0; i < Global.HorNum; i++) {
                    for (let j = Global.VerNum - 1; j >= 0; j--) {
                        if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) {
                            let move_num: number = 0;
                            for (let k = Global.VerNum - 1; k > j; k--) {
                                if (!this.SpriteArr[i][k].getComponent(GameSingleSprite).IsShow) {
                                    move_num++;
                                }
                            }
                            if (move_num > 0) {
                                this.SpriteArr[i][j + move_num].getComponent(GameSingleSprite).UpdateSpriteStyle(this.SpriteArr[i][j].getComponent(GameSingleSprite).SpriteInfo);
                                this.SpriteArr[i][j + move_num].getComponent(GameSingleSprite).PlaySlideAni(Direction.DOWN, move_num);
                                this.SpriteArr[i][j].getComponent(GameSingleSprite).Init();
                                is_play = true;
                            }
                        }
                    }
                }
                break;
            case Direction.DOWN://整体向下移动
                for (let i = 0; i < Global.HorNum; i++) {
                    for (let j = 0; j < Global.VerNum; j++) {
                        if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) {
                            let move_num: number = 0;
                            for (let k = 0; k < j; k++) {
                                if (!this.SpriteArr[i][k].getComponent(GameSingleSprite).IsShow) {
                                    move_num++;
                                }
                            }
                            if (move_num > 0) {
                                this.SpriteArr[i][j - move_num].getComponent(GameSingleSprite).UpdateSpriteStyle(this.SpriteArr[i][j].getComponent(GameSingleSprite).SpriteInfo);
                                this.SpriteArr[i][j - move_num].getComponent(GameSingleSprite).PlaySlideAni(Direction.UP, move_num);
                                this.SpriteArr[i][j].getComponent(GameSingleSprite).Init();
                                is_play = true;
                            }
                        }
                    }
                }
                break;
            case Direction.LEFT://整体向左移动
                for (let i = 0; i < Global.HorNum; i++) {
                    for (let j = 0; j < this.SpriteArr[i].length; j++) {
                        if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) {
                            let move_num: number = 0;
                            //判断右侧差多少个
                            for (let k = 0; k < i; k++) {
                                if (!this.SpriteArr[k][j].getComponent(GameSingleSprite).IsShow) {
                                    move_num++;
                                }
                            }
                            if (move_num > 0) {
                                this.SpriteArr[i - move_num][j].getComponent(GameSingleSprite).UpdateSpriteStyle(this.SpriteArr[i][j].getComponent(GameSingleSprite).SpriteInfo);
                                this.SpriteArr[i - move_num][j].getComponent(GameSingleSprite).PlaySlideAni(Direction.LEFT, move_num);
                                this.SpriteArr[i][j].getComponent(GameSingleSprite).Init();
                                is_play = true;
                            }
                        }
                    }
                }
                break;
            case Direction.RIGHT://整体向右移动
                for (let i = Global.HorNum - 1; i >= 0; i--) {
                    for (let j = 0; j < this.SpriteArr[i].length; j++) {
                        if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) {
                            let move_num: number = 0;
                            //判断右侧差多少个
                            for (let k = Global.HorNum - 1; k > i; k--) {
                                if (!this.SpriteArr[k][j].getComponent(GameSingleSprite).IsShow) {
                                    move_num++;
                                }
                            }
                            if (move_num > 0) {
                                this.SpriteArr[i + move_num][j].getComponent(GameSingleSprite).UpdateSpriteStyle(this.SpriteArr[i][j].getComponent(GameSingleSprite).SpriteInfo);
                                this.SpriteArr[i + move_num][j].getComponent(GameSingleSprite).PlaySlideAni(Direction.RIGHT, move_num);
                                this.SpriteArr[i][j].getComponent(GameSingleSprite).Init();
                                is_play = true;
                            }
                        }
                    }
                }
                break;
        }
        if (is_play) AudioMgr.instance.PlayEffect(SoundName.Choose);
    }

    /**
     * 判断消失
     */
    public CheckDisappear(): void {
        this.AllAddScoreSprites = [];

        for (let i = 0; i < Global.HorNum; i++) {
            for (let j = 0; j < Global.VerNum; j++) {
                if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) {
                    this.NeightSameSprites = [];
                    this.CheckNeightSameSprite(this.SpriteArr[i][j], i, j);
                    if (this.NeightSameSprites.length > 2) {
                        for (let single_sprite of this.NeightSameSprites) this.AddScoreSprite(single_sprite);
                    }
                }
            }
        }

        //如果有可以消除的
        if (this.AllAddScoreSprites.length > 0) {
            for (let single_sprite of this.AllAddScoreSprites) single_sprite.getComponent(GameSingleSprite).IsClear = true;
            this.CheckScore();
        } else {
            this.CheckCanMove();
            UIMgr.Instance.HideTop(AssetList.Top.NoTouch);
        }

    }

    /**
     * 检测相邻得精灵
     */
    private CheckNeightSameSprite(_sprite: Node, _hor: number, _ver: number): void {
        if (this.NeightSameSprites.indexOf(_sprite) != -1) return;

        this.NeightSameSprites.push(_sprite);

        let sprite_info: SpriteInfo = _sprite.getComponent(GameSingleSprite).SpriteInfo;

        //左侧判断
        if (_hor > 0 && this.SpriteArr[_hor - 1][_ver].getComponent(GameSingleSprite).IsShow && this.SpriteArr[_hor - 1][_ver].getComponent(GameSingleSprite).SpriteInfo.type == sprite_info.type) {
            this.CheckNeightSameSprite(this.SpriteArr[_hor - 1][_ver], _hor - 1, _ver);
        }

        //右侧判断
        if (_hor < Global.HorNum - 1 && this.SpriteArr[_hor + 1][_ver].getComponent(GameSingleSprite).IsShow && this.SpriteArr[_hor + 1][_ver].getComponent(GameSingleSprite).SpriteInfo.type == sprite_info.type) {
            this.CheckNeightSameSprite(this.SpriteArr[_hor + 1][_ver], _hor + 1, _ver);
        }

        //上方
        if (_ver > 0 && this.SpriteArr[_hor][_ver - 1].getComponent(GameSingleSprite).IsShow && this.SpriteArr[_hor][_ver - 1].getComponent(GameSingleSprite).SpriteInfo.type == sprite_info.type) {
            this.CheckNeightSameSprite(this.SpriteArr[_hor][_ver - 1], _hor, _ver - 1);
        }

        //下方
        if (_ver < Global.VerNum - 1 && this.SpriteArr[_hor][_ver + 1].getComponent(GameSingleSprite).IsShow && this.SpriteArr[_hor][_ver + 1].getComponent(GameSingleSprite).SpriteInfo.type == sprite_info.type) {
            this.CheckNeightSameSprite(this.SpriteArr[_hor][_ver + 1], _hor, _ver + 1);
        }
    }

    /**
     * 添加得分砖块
     */
    public AddScoreSprite(_sprite: Node) {
        if (this.AllAddScoreSprites.indexOf(_sprite) == -1) {
            this.AllAddScoreSprites.push(_sprite);
        }
    }

    /**
     * 判断得分
     */
    public CheckScore() {
        UIMgr.Instance.ShowTop(AssetList.Top.NoTouch);
        for (let single_sprite of this.AllAddScoreSprites) {
            single_sprite.getComponent(GameSingleSprite).PlayCanClearAni();
            this.ScreoLoad.getComponent(EleScoreLoad).GetScore(GAMEDATA.AddScore, single_sprite.getPosition());
            GameScene.Instance.UpdateScore(GAMEDATA.AddScore);
        }
        AudioMgr.instance.PlayEffect(SoundName.Clear);
        //再次移动
        this.scheduleOnce(() => {
            UIMgr.Instance.HideTop(AssetList.Top.NoTouch);
            this.AllMove();
            this.CheckDisappear();
        }, Global.PlayDisTime * 3 + 0.1)
    }

    /**
     * 判断是否可以移动
     */
    public CheckCanMove() {
        // this.HorCanMove = true;
        // this.VerCanMove = true;

        // for (let i = 0; i < Global.HorNum; i++) {
        //     let hor_num: number = 0;
        //     let ver_num: number = 0;
        //     for (let j = 0; j < Global.VerNum; j++) {
        //         if (this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow) hor_num++
        //         if (this.SpriteArr[j][i].getComponent(GameSingleSprite).IsShow) ver_num++;
        //     }

        //     if (hor_num == Global.HorNum) this.VerCanMove = false;
        //     if (ver_num == Global.VerNum) this.HorCanMove = false;

        // }

        // if (!this.HorCanMove && !this.VerCanMove) {
        //     console.log("游戏结束");
        // }

        let have_move: boolean = false;

        //只要又空位就是能移动得
        for (let i = 0; i < this.SpriteArr.length; i++) {
            for (let j = 0; j < this.SpriteArr[i].length; j++) {
                if (!this.SpriteArr[i][j].getComponent(GameSingleSprite).IsShow || !this.SpriteArr[j][i].getComponent(GameSingleSprite).IsShow) {
                    have_move = true;
                    break;
                }
            }
        }

        if (!have_move) {
            GameScene.Instance.GameOver();
        }

    }

}



